home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 176-200 / 190 / nethack / twee.zoo / eat.c < prev    next >
C/C++ Source or Header  |  1988-07-22  |  14KB  |  605 lines

  1. /*    SCCS Id: @(#)eat.c      2.3     87/12/16
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include    "hack.h"
  5. #ifdef KAA
  6. char POISONOUS[] = "ADKSVabhks&";
  7. #else
  8. char POISONOUS[] = "ADKSVabhks";
  9. #endif
  10. extern char *nomovemsg;
  11. extern int (*afternmv)();
  12. extern int (*occupation)();
  13. extern char *occtxt;
  14. extern struct obj *splitobj(), *addinv();
  15.  
  16. /* hunger texts used on bottom line (each 8 chars long) */
  17. #define SATIATED    0
  18. #define NOT_HUNGRY    1
  19. #define HUNGRY        2
  20. #define WEAK        3
  21. #define FAINTING    4
  22. #define FAINTED     5
  23. #define STARVED     6
  24.  
  25. char *hu_stat[] = {
  26.     "Satiated",
  27.     "        ",
  28.     "Hungry  ",
  29.     "Weak    ",
  30.     "Fainting",
  31.     "Fainted ",
  32.     "Starved "
  33. };
  34.  
  35. init_uhunger(){
  36.     u.uhunger = 900;
  37.     u.uhs = NOT_HUNGRY;
  38. }
  39.  
  40. struct { char *txt; int nut; } tintxts[] = {
  41.     "It contains salmon - not bad!",        60,
  42.     "It contains first quality peaches - what a surprise!", 40,
  43.     "It contains apple juice - perhaps not what you hoped for.", 20,
  44.     "It contains some nondescript substance, tasting awfully.", 500,
  45.     "It contains rotten meat. You vomit.", -50,
  46.     "It turns out to be empty.",    0
  47. };
  48. #define TTSZ    SIZE(tintxts)
  49.  
  50. static struct {
  51.     struct obj *tin;
  52.     int usedtime, reqtime;
  53. } tin;
  54.  
  55. opentin(){
  56.     register int r;
  57.  
  58.     if(!carried(tin.tin))           /* perhaps it was stolen? */
  59.         return(0);              /* %% probably we should use tinoid */
  60.     if(tin.usedtime++ >= 50) {
  61.         pline("You give up your attempt to open the tin.");
  62.         return(0);
  63.     }
  64.     if(tin.usedtime < tin.reqtime)
  65.         return(1);              /* still busy */
  66.  
  67.     pline("You succeed in opening the tin.");
  68.     useup(tin.tin);
  69.     r = rn2(2*TTSZ);
  70.     if(r < TTSZ) {
  71.         pline(tintxts[r].txt);
  72.         lesshungry(tintxts[r].nut);
  73.         /* check for vomiting added by GAN 01/16/87 */
  74.         if(tintxts[r].nut < 0 && Sick) {
  75.         Sick = 0;
  76.         pline("What a relief!");
  77.         }
  78.         if(r == 0) {                        /* Salmon */
  79.         Glib = rnd(15);
  80.         pline("Eating salmon made your fingers very slippery.");
  81.         }
  82.     } else {
  83.         pline("It contains spinach - this makes you feel like %s!",
  84.         Hallucination ? "Swee'pea" : "Popeye");
  85.  
  86.         lesshungry(600);
  87.         gainstr(0);
  88.     }
  89.     return(0);
  90. }
  91.  
  92. Meatdone(){
  93.     u.usym = '@';
  94.     prme();
  95. }
  96.  
  97. doeat(){
  98.     register struct obj *otmp;
  99.     register struct objclass *ftmp;
  100.     register tmp;
  101.  
  102.     /* Is there some food (probably a heavy corpse) here on the ground? */
  103.     if(!Levitation)
  104.     for(otmp = fobj; otmp; otmp = otmp->nobj) {
  105.         if(otmp->ox == u.ux && otmp->oy == u.uy &&
  106.            otmp->olet == FOOD_SYM) {
  107.             pline("There %s %s here; eat %s? [ny] ",
  108.                 (otmp->quan == 1) ? "is" : "are",
  109.                 doname(otmp),
  110.                 (otmp->quan == 1) ? "it" : "one");
  111.             if(readchar() == 'y') {
  112.                 if(otmp->quan != 1)
  113.                     (void) splitobj(otmp, 1);
  114.                 freeobj(otmp);
  115.                 otmp = addinv(otmp);
  116.                 addtobill(otmp);
  117.                 if(Invisible) newsym(u.ux, u.uy);
  118.                 goto gotit;
  119.             }
  120.         }
  121.     }
  122.     otmp = getobj("%", "eat");
  123.     if(!otmp) return(0);
  124. gotit:
  125.     if(otmp->otyp == TIN) {
  126.         if(uwep) {
  127.             switch(uwep->otyp) {
  128.             case CAN_OPENER:
  129.                 tmp = 1;
  130.                 break;
  131.             case DAGGER:
  132.             case CRYSKNIFE:
  133.                 tmp = 3;
  134.                 break;
  135.             case PICK_AXE:
  136.             case AXE:
  137.                 tmp = 6;
  138.                 break;
  139.             default:
  140.                 goto no_opener;
  141.             }
  142.             pline("Using your %s you try to open the tin.",
  143.                 aobjnam(uwep, (char *) 0));
  144.         } else {
  145.         no_opener:
  146.             pline("It is not so easy to open this tin.");
  147.             if(Glib) {
  148.                 pline("The tin slips out of your hands.");
  149.                 if(otmp->quan > 1) {
  150.                     register struct obj *obj;
  151.                     extern struct obj *splitobj();
  152.  
  153.                     obj = splitobj(otmp, 1);
  154.                     if(otmp == uwep) setuwep(obj);
  155.                 }
  156.                 dropx(otmp);
  157.                 return(1);
  158.             }
  159.             tmp = 10 + rn2(1 + 500/((int)(u.ulevel + u.ustr)));
  160.         }
  161.         tin.reqtime = tmp;
  162.         tin.usedtime = 0;
  163.         tin.tin = otmp;
  164. #ifdef DGK
  165.         set_occupation(opentin, "opening the tin", 0);
  166. #else
  167.         occupation = opentin;
  168.         occtxt = "opening the tin";
  169. #endif
  170.         return(1);
  171.     }
  172.     ftmp = &objects[otmp->otyp];
  173.     multi = -ftmp->oc_delay;
  174.     if(otmp->otyp >= CORPSE && eatcorpse(otmp)) goto eatx;
  175. #ifdef DGKMOD
  176.     if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE && otmp->otyp != DEAD_LIZARD) {
  177. #else
  178.     if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
  179. #endif
  180. #ifdef KAA
  181.         if (otmp->otyp == DEAD_VIOLET_FUNGUS)
  182.             pline("Seems rather stale though...");
  183.         else
  184. #endif
  185.         pline("Blecch!  Rotten food!");
  186.         if(!rn2(4)) {
  187.             if (Hallucination) pline("You feel rather trippy.");
  188.             else
  189.                 pline("You feel rather light headed.");
  190.             HConfusion += d(2,4);
  191.         } else if(!rn2(4) && !Blind) {
  192.             pline("Everything suddenly goes dark.");
  193.             Blinded = d(2,10);
  194.             seeoff(0);
  195.         } else if(!rn2(3)) {
  196.             if(Blind)
  197.               pline("The world spins and you slap against the floor.");
  198.             else
  199.               pline("The world spins and goes dark.");
  200.             nomul(-rnd(10));
  201.             nomovemsg = "You are conscious again.";
  202.         }
  203.         lesshungry(ftmp->nutrition / 4);
  204.     } else {
  205.         if(u.uhunger >= 1500) choke(ftmp);
  206.  
  207.         switch(otmp->otyp){
  208.         case FOOD_RATION:
  209.             if(u.uhunger <= 200)
  210.                 if (Hallucination)
  211.                 pline("Oh wow, like superior man!");
  212.                 else
  213.                 pline("That food really hit the spot!");
  214.             else if(u.uhunger <= 700)
  215.                 pline("That satiated your stomach!");
  216. #ifdef DGKMOD
  217.     /* Have lesshungry() report when you're nearly full so all eating
  218.      * warns when you're about to choke.
  219.      */
  220.             lesshungry(ftmp->nutrition);
  221. #else
  222.             else {
  223.     pline("You're having a hard time getting all that food down.");
  224.                 multi -= 2;
  225.             }
  226.             lesshungry(ftmp->nutrition);
  227.             if(multi < 0) nomovemsg = "You finished your meal.";
  228. #endif /* DGKMOD /**/
  229.             break;
  230.         case TRIPE_RATION:
  231.             if (u.usym != '@')
  232.                 pline("That tripe ration was surprisingly good!");
  233.             else {
  234.                 pline("Yak - dog food!");
  235.                 more_experienced(1,0);
  236.                 flags.botl = 1;
  237.             }
  238.             if(rn2(2) && u.usym == '@'){
  239.                 pline("You vomit.");
  240.                 morehungry(20);
  241.                 if(Sick) {
  242.                     Sick = 0;    /* David Neves */
  243.                     pline("What a relief!");
  244.                 }
  245.             } else    lesshungry(ftmp->nutrition);
  246.             break;
  247.         default:
  248.             if(u.usym == '@' && otmp->otyp >= CORPSE) {
  249. #ifdef KAA
  250.                 if(otmp->otyp != DEAD_VIOLET_FUNGUS)
  251. #endif
  252.                 pline("That %s tasted terrible!",ftmp->oc_name);
  253.             } else
  254.             pline("That %s was delicious!",ftmp->oc_name);
  255.             lesshungry(ftmp->nutrition);
  256. #ifdef DGKMOD
  257.             /* Relief from cockatrices -dgk */
  258.             if (otmp->otyp == DEAD_LIZARD) {
  259.                 if (Stoned) {
  260.                     Stoned = 0;
  261.                     pline("You feel more limber!");
  262.                 }
  263.                 if (HConfusion > 2)
  264.                     HConfusion = 2;
  265.             }
  266. #else
  267.             if(otmp->otyp == DEAD_LIZARD && (HConfusion > 2))
  268.                 HConfusion = 2;
  269. #endif /* DGKMOD /**/
  270.             else
  271. #ifdef QUEST
  272.             if(otmp->otyp == CARROT && !Blind) {
  273.                 u.uhorizon++;
  274.                 setsee();
  275.                 pline("Your vision improves.");
  276.             } else
  277. #endif
  278. #ifdef KAA
  279.             if(otmp->otyp == CARROT && Blind) Blinded = 1;
  280.             else
  281. #endif
  282.             if(otmp->otyp == FORTUNE_COOKIE) {
  283.               if(Blind) {
  284.                 pline("This cookie has a scrap of paper inside!");
  285.                 pline("What a pity, that you cannot read it!");
  286.               } else
  287.                 outrumor();
  288.             } else
  289.             if(otmp->otyp == LUMP_OF_ROYAL_JELLY) {
  290.                 /* This stuff seems to be VERY healthy! */
  291.                 gainstr(1);
  292.                 u.uhp += rnd(20);
  293.                 if(u.uhp > u.uhpmax) {
  294.                     if(!rn2(17)) u.uhpmax++;
  295.                     u.uhp = u.uhpmax;
  296.                 }
  297.                 heal_legs();
  298.             }
  299.             break;
  300.         }
  301.     }
  302. eatx:
  303.     if(multi<0 && !nomovemsg){
  304.         static char msgbuf[BUFSZ];
  305.         (void) sprintf(msgbuf, "You finished eating the %s.",
  306.                 ftmp->oc_name);
  307.         nomovemsg = msgbuf;
  308.     }
  309.     useup(otmp);
  310.     return(1);
  311. }
  312.  
  313. /* called in main.c */
  314. gethungry(){
  315.     --u.uhunger;
  316.     if(moves % 2) {
  317.         if(HRegeneration) u.uhunger--;
  318.         if(Hunger) u.uhunger--;
  319.         /* a3:    if(Hunger & LEFT_RING) u.uhunger--;
  320.             if(Hunger & RIGHT_RING) u.uhunger--;
  321.            etc. */
  322.     }
  323.     if(moves % 20 == 0) {                   /* jimt@asgb */
  324.         if(uleft) u.uhunger--;
  325.         if(uright) u.uhunger--;
  326.     }
  327.     newuhs(TRUE);
  328. }
  329.  
  330. /* called after vomiting and after performing feats of magic */
  331. morehungry(num) register num; {
  332.     u.uhunger -= num;
  333.     newuhs(TRUE);
  334. }
  335.  
  336. /* called after eating something (and after drinking fruit juice) */
  337. lesshungry(num) register num; {
  338.     u.uhunger += num;
  339.     if(u.uhunger >= 2000) choke((struct objclass *) 0);
  340. #ifdef DGKMOD
  341.     else {
  342.         /* Have lesshungry() report when you're nearly full so all eating
  343.          * warns when you're about to choke.
  344.          */
  345.         if (u.uhunger >= 1500) {
  346.         pline("You're having a hard time getting all of it down.");
  347.         multi -= 2;
  348.         nomovemsg = "You're finally finished.";
  349.         }
  350.     }
  351. #endif /* DGKMOD /**/
  352.     newuhs(FALSE);
  353. }
  354.  
  355. unfaint(){
  356.     u.uhs = FAINTING;
  357.     flags.botl = 1;
  358. }
  359.  
  360. newuhs(incr) boolean incr; {
  361.     register int newhs, h = u.uhunger;
  362.  
  363.     newhs = (h > 1000) ? SATIATED :
  364.         (h > 150) ? NOT_HUNGRY :
  365.         (h > 50) ? HUNGRY :
  366.         (h > 0) ? WEAK : FAINTING;
  367.  
  368.     if(newhs == FAINTING) {
  369.         if(u.uhs == FAINTED) newhs = FAINTED;
  370.         if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
  371.             if(u.uhs != FAINTED && multi >= 0 /* %% */) {
  372.                 pline("You faint from lack of food.");
  373.                 nomul(-10+(u.uhunger/10));
  374.                 nomovemsg = "You regain consciousness.";
  375.                 afternmv = unfaint;
  376.                 newhs = FAINTED;
  377.             }
  378.         } else
  379.         if(u.uhunger < -(int)(200 + 25*u.ulevel)) {
  380.             u.uhs = STARVED;
  381.             flags.botl = 1;
  382.             bot();
  383.             pline("You die from starvation.");
  384.             done("starved");
  385.         }
  386.     }
  387.  
  388.     if(newhs != u.uhs) {
  389.         if(newhs >= WEAK && u.uhs < WEAK)
  390.             losestr(1);     /* this may kill you -- see below */
  391.         else
  392.         if(newhs < WEAK && u.uhs >= WEAK && u.ustr < u.ustrmax)
  393.             losestr(-1);
  394.         switch(newhs){
  395.         case HUNGRY:
  396.             if (Hallucination) {
  397.                 pline((!incr) ?
  398.                 "You now have a lesser case of the munchies." :
  399.                 "You are getting the munchies.");
  400.             } else
  401.                 pline((!incr) ? "You only feel hungry now." :
  402.                   (u.uhunger < 145) ? "You feel hungry." :
  403.                    "You are beginning to feel hungry.");
  404.             break;
  405.         case WEAK:
  406.             if (Hallucination)
  407.                 pline((!incr) ?
  408.                   "You still have the munchies." :
  409.                   "The munchies are starting to interfere with your motor capabilities.");
  410.             else
  411.                 pline((!incr) ? "You feel weak now." :
  412.                   (u.uhunger < 45) ? "You feel weak." :
  413.                    "You are beginning to feel weak.");
  414.             break;
  415.         }
  416.         u.uhs = newhs;
  417.         flags.botl = 1;
  418.         if(u.uhp < 1) {
  419.             pline("You die from hunger and exhaustion.");
  420.             killer = "exhaustion";
  421.             done("starved");
  422.         }
  423.     }
  424. }
  425.  
  426. #define CORPSE_I_TO_C(otyp)     (char) ((otyp >= DEAD_ACID_BLOB)\
  427.              ?    'a' + (otyp - DEAD_ACID_BLOB)\
  428.              :    '@' + (otyp - DEAD_HUMAN))
  429. poisonous(otmp)
  430. register struct obj *otmp;
  431. {
  432. #ifdef KAA
  433.     if(otmp->otyp == DEAD_DEMON) return(1);
  434. #endif
  435.     return(index(POISONOUS, CORPSE_I_TO_C(otmp->otyp)) != 0);
  436. }
  437.  
  438. /* returns 1 if some text was printed */
  439. eatcorpse(otmp) register struct obj *otmp; {
  440. #ifdef KAA
  441. register char let;
  442. #else
  443. register char let = CORPSE_I_TO_C(otmp->otyp);
  444. #endif
  445. register tp = 0;
  446. #ifdef KAA
  447.     if(otmp->otyp == DEAD_DEMON) let='&';
  448.     else if (otmp->otyp == DEAD_GIANT) let='9';
  449.     else let = CORPSE_I_TO_C(otmp->otyp);
  450. #endif
  451. #ifdef SAC
  452.     if(otmp->otyp == DEAD_SOLDIER) let='3';
  453. #endif /* SAC */
  454.     if(let != 'a' && moves > otmp->age + 50 + rn2(100)) {
  455.         tp++;
  456.         pline("Ulch -- that meat was tainted!");
  457.         pline("You get very sick.");
  458.         Sick = 10 + rn2(10);
  459.         u.usick_cause = objects[otmp->otyp].oc_name;
  460.     } else if(index(POISONOUS, let) && rn2(5)){
  461.         tp++;
  462.         pline("Ecch -- that must have been poisonous!");
  463.         if(!Poison_resistance){
  464.             losestr(rnd(4));
  465.             losehp(rnd(15), "poisonous corpse");
  466.         } else
  467.             pline("You don't seem affected by the poison.");
  468.     } else if(index("ELNOPQRUuxz", let) && rn2(5)){
  469.         tp++;
  470.         pline("You feel sick.");
  471.         losehp(rnd(8), "cadaver");
  472.     }
  473.     switch(let) {
  474.     case 'L':
  475.     case 'N':
  476.     case 't':
  477. #ifdef KAA
  478.     case 'Q':
  479. #endif
  480.         HTeleportation |= INTRINSIC;
  481.         break;
  482.     case 'W':
  483.         pluslvl();
  484.         break;
  485.     case 'n':
  486.         u.uhp = u.uhpmax;
  487.         flags.botl = 1;
  488.         /* fall into next case */
  489. #ifdef SAC
  490.     case '3':
  491. #endif
  492.     case '@':
  493.         pline("You cannibal! You will be sorry for this!");
  494.         /* not tp++; */
  495.         /* fall into next case */
  496.     case 'd':
  497.         Aggravate_monster |= INTRINSIC;
  498.         break;
  499.     case 'I':
  500.         if(!Invis) {
  501.             HInvis = 50+rn2(100);
  502.             if(!See_invisible)
  503.                 newsym(u.ux, u.uy);
  504.         } else {
  505.             HInvis |= INTRINSIC;
  506.             HSee_invisible |= INTRINSIC;
  507.         }
  508.         /* fall into next case */
  509.     case 'y':
  510. #ifdef QUEST
  511.         u.uhorizon++;
  512. #endif
  513.         /* fall into next case */
  514.     case 'B':
  515.         HConfusion += 50;
  516.         break;
  517.     case 'D':
  518.         HFire_resistance |= INTRINSIC;
  519.         break;
  520.     case 'E':
  521.         HTelepat |= INTRINSIC;
  522.         break;
  523.     case 'F':
  524.     case 'Y':
  525.         HCold_resistance |= INTRINSIC;
  526.         break;
  527. #ifdef KAA
  528.     case '9':
  529.         gainstr(1);
  530.         break;
  531. #endif
  532. #ifdef KJSMODS
  533.     case 'S':       /* if a snake can kill you with poison, at least
  534.              * have the possibility of getting resistance */
  535.         if ( rn2(5) ) break;
  536.         /* fall into next case */
  537. #endif
  538.     case 'k':
  539.     case 's':
  540.         HPoison_resistance |= INTRINSIC;
  541.         break;
  542.     case 'c':
  543.         if (u.usym != 'c') {
  544.  
  545.             pline("You turn to stone.");
  546.             killer = "dead cockatrice";
  547.             done("died");
  548.         }
  549.         break;
  550.     case 'a':
  551.       if(Stoned) {
  552.           pline("What a pity - you just destroyed a future piece of art!");
  553.           tp++;
  554.           Stoned = 0;
  555.       }
  556.       break;
  557. #ifdef KAA
  558.     case 'v':
  559.         pline ("Oh wow!  Great stuff!");
  560.         Hallucination += 200;
  561.         setsee();
  562.         break;
  563. #endif
  564.     case 'M':
  565.         if(u.usym == '@') {
  566.             pline("You cannot resist the temptation to mimic a treasure chest.");
  567.             tp++;
  568.             nomul(-30);
  569.             afternmv = Meatdone;
  570.             nomovemsg = "You now again prefer mimicking a human.";
  571.             u.usym = GOLD_SYM;
  572.             prme();
  573.         }
  574.         break;
  575.     }
  576.     return(tp);
  577. }
  578.  
  579. /* Created by GAN 01/28/87
  580.  * Amended by AKP 09/22/87: if not hard, don't choke, just vomit.
  581.  *
  582.  * Note that if you have enough food, you can always stop being Sick!
  583.  * choke() returns if you don't choke, kills you if you do.
  584.  */
  585. choke(food)
  586. register struct objclass *food;
  587. {
  588.     /* only happens if you were satiated */
  589.     if(u.uhs != SATIATED) return;
  590. #ifdef HARD
  591.     if(food)        killer = food->oc_name;
  592.     else        killer = "exuberant appetite";
  593.     pline("You choke over your food.");
  594.     pline("You die...");
  595.     done("choked");
  596. #else
  597.     pline("You stuff yourself and then vomit voluminously.");
  598.     morehungry(1000);       /* you just got *very* sick! */
  599.     if(Sick) {
  600.         Sick = 0;    /* A good idea from David Neves */
  601.         pline("What a relief!");
  602.     }
  603. #endif
  604. }
  605.